package com.wiz.netty.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wiz.log.NettyInfoRecord;
import com.wiz.netty.message.NettyMessageFactory;
import com.wiz.netty.message.NettyMessageTO;
import com.wiz.web.manager.ServiceManager;

public class IdleHandler extends AbstractHandlerAdapter {
	private transient final Logger log = LoggerFactory.getLogger(getClass());
	
	public IdleHandler(ServiceManager serviceManager){
		super();
		this.serviceManager = serviceManager;
	}
	
	/**
	 *  channelDisconnected, channelUnbound, 和channelClosed触发后，执行channelInactive
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		destroyHandler(ctx,"IdleHandler.channelInactive must disconnected");
	}
	
	@Override
	public void channelRead(ChannelHandlerContext ctx,Object msg) throws Exception{
		NettyMessageTO.MessageContent message = (NettyMessageTO.MessageContent)msg;
		if(message.getType() == 0){
			//有效心跳信息,暂不做任何操作
//			NettyInfoRecord.infoRecord(String.format(IDLE_MSG, message.getIden().toStringUtf8()));
		}else{
			ctx.fireChannelRead(msg);
		}
	}
	
	/**
	 * 服务器触发事件
	 */
	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object event) throws Exception {
		if (event instanceof IdleStateEvent) {
			IdleStateEvent e = (IdleStateEvent) event;
            if (e.state() == IdleState.READER_IDLE) {//一段时间没有收到心跳
            	NettyInfoRecord.warnRecord("stationId= "+serviceManager.getKeyByValue(ctx)+" disconnect because of idle be overdue");
            	destroyHandler(ctx,"IdleHandler.userEventTriggered disconnect because of idle be overdue");
            }else if (e.state() == IdleState.WRITER_IDLE) {
//            	NettyInfoRecord.infoRecord("netty server send writeIdel to "+serviceManager.getKeyByValue(ctx));
            	ctx.writeAndFlush(NettyMessageFactory.getInstance().getIdleMessage());
            }else if (e.state() == IdleState.ALL_IDLE) {
            	log.warn("stationId= "+serviceManager.getKeyByValue(ctx)+" must disconnected");
            	destroyHandler(ctx,"IdleHandler.userEventTriggered must disconnected");
			}
        }  
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause){
		NettyInfoRecord.errorRecord(cause.getMessage()+" in IdleHandler");
	}
}

